﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using App1AppHandler;

namespace Reborn_Server.App1AppHandler
{
    public class Spell_Hide : Buff
    {
        public Spell_Hide()
        {
            minutesLeft = 10;
        }

        public override bool castWhileAlone(SpellIcon sIcon)
        {
            return true;
        }

        public bool canSeeThrough(CreatureBase creatureBase)
        {
            int hidePower = 0;
            if (spellIcon.Name.IndexOf("Rank 2") > -1)
                hidePower = SkillManager.AdjustForCombat(CastingCreatureLevel, 70, CastingCreatureWis);
            else
                hidePower = SkillManager.AdjustForCombat(CastingCreatureLevel, 10, CastingCreatureWis);

            if (creatureBase.getResist(spellIcon.Skill) > hidePower)
                return true;

            return false;
        }

        override public void Resume(CreatureBase targetCreatureBase, SpellIcon _spellIcon, int timeRemaining, int castLevel, int castCharacterID, int castInt, int castWis, int optionalValue, string xmlData)
        {
            TargetCreatureBase = targetCreatureBase;

            //We need to check to see if we can hide in this position (May have portaled somewhere non-hidable) before calling base.Resume
            bool canHide = false;
            LockItem lockitem = TargetCreatureBase.GameHandler.GetLockItem(TargetCreatureBase.MapID, TargetCreatureBase.Instance);
            lock (lockitem.LockObj)
            {
                Map CurrentMap = TargetCreatureBase.GameHandler.GetMap(TargetCreatureBase.MapID, TargetCreatureBase.Instance);

                MapItem CurrentMapItem = null;
                List<Character> CharactersInRange = new List<Character>();
                foreach (MapItem mapitem in CurrentMap.MapItems)
                {
                    if (Math.Abs(mapitem.MapX - TargetCreatureBase.MapX) <= 4 && Math.Abs(mapitem.MapY - TargetCreatureBase.MapY) <= 4)
                    {
                        foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                        {
                            if (creaturebase is Character && creaturebase != TargetCreatureBase)
                                CharactersInRange.Add((Character)creaturebase);
                        }
                    }
                    if (Math.Abs(mapitem.MapX - TargetCreatureBase.MapX) <= 1 && Math.Abs(mapitem.MapY - TargetCreatureBase.MapY) <= 1)
                    {
                        if (mapitem.TerrainUrl != "")
                            canHide = true;
                    }
                    if (mapitem.MapX == TargetCreatureBase.MapX && mapitem.MapY == TargetCreatureBase.MapY && mapitem.isDark(null) == true)
                        canHide = true;

                    if (mapitem.MapX == TargetCreatureBase.MapX && mapitem.MapY == TargetCreatureBase.MapY)
                        CurrentMapItem = mapitem;
                }
                if (canHide == true)
                {
                    foreach (Character character in CharactersInRange)
                    {
                        character.AddMapItem(CurrentMapItem);
                    }
                }
                else
                {
                    if (TargetCreatureBase is Character)
                    {
                        Character character = (Character)TargetCreatureBase;

                        character.buffManager.RemoveBuff(this);

                        Message msg = new Message();
                        msg.CreatureID = character.CreatureID;
                        msg.Type = "server";
                        msg.Text = "Nowhere to hide!";

                        character.AddMessage(msg);
                    }
                }
            }
            if (canHide)
            {
                minutesLeft = timeRemaining;
                base.Resume(targetCreatureBase, _spellIcon, timeRemaining, castLevel, castCharacterID, castInt, castWis, optionalValue, xmlData);

                spellTimer.Start();
            }            
        }

        public void Cast(CreatureBase myCreatureBase, int CastLevel, long CreatureGUID)
        {
            Loot leftHandItem = myCreatureBase.LeftHand;
            if (leftHandItem != null)
            {
                bool isRange = false;
                bool isMelee = false;
                if (leftHandItem is Weapon)
                {
                    Weapon leftHandWeapon = (Weapon)leftHandItem;
                    isRange = leftHandWeapon.Range;
                    isMelee = leftHandWeapon.Melee;
                }
                bool canHideWith = false;
                if (leftHandItem.Bag == true)
                    canHideWith = true;
                if (isRange == true && isMelee == false)
                    canHideWith = true;

                if (canHideWith == false)
                {
                    myCreatureBase.SendMessage("You can only hide holding range weapons, or items that can fit in your bag.", "server");
                    if (myCreatureBase is Character)
                    {
                        Character myChar = (Character)myCreatureBase;
                        myChar.PlaySound("Ding", myChar.MapX, myChar.MapY);
                        myChar.SetBusy(false);
                    }

                    return;
                }
            }

            Loot rightHandItem = myCreatureBase.RightHand;
            if (rightHandItem != null)
            {
                bool isRange = false;
                bool isMelee = false;
                if (rightHandItem is Weapon)
                {
                    Weapon rightHandWeapon = (Weapon)rightHandItem;
                    isRange = rightHandWeapon.Range;
                    isMelee = rightHandWeapon.Melee;
                }
                bool canHideWith = false;
                if (rightHandItem.Bag == true)
                    canHideWith = true;
                if (isRange == true && isMelee == false)
                    canHideWith = true;

                if (canHideWith == false)
                {
                    myCreatureBase.SendMessage("You can only hide holding range weapons, or items that can fit in your bag.", "server");
                    if (myCreatureBase is Character)
                    {
                        Character myChar = (Character)myCreatureBase;
                        myChar.PlaySound("Ding", myChar.MapX, myChar.MapY);
                        myChar.SetBusy(false);
                    }

                    return;
                }
            }

            List<MapItem> MapItemsWithin12;
            if (base.InitializeCast(myCreatureBase, CastLevel, CreatureGUID, true, out MapItemsWithin12) == false)
                return;

            minutesLeft = System.Convert.ToInt32(Math.Floor(CastingCreatureWis / 2.00));

            MapItem CurrentMapItem = null;
            List<Character> CharactersInRange = new List<Character>();
            bool removeHide = true;
            foreach (MapItem mapitem in MapItemsWithin12)
            {
                if (Math.Abs(mapitem.MapX - myCreatureBase.MapX) <= 4 && Math.Abs(mapitem.MapY - myCreatureBase.MapY) <= 4)
                {
                    foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                    {
                        if (creaturebase is Character && creaturebase != myCreatureBase)
                            CharactersInRange.Add((Character)creaturebase);
                    }
                }
                if (Math.Abs(mapitem.MapX - myCreatureBase.MapX) <= 1 && Math.Abs(mapitem.MapY - myCreatureBase.MapY) <= 1)
                {
                    if (mapitem.TerrainUrl != "")
                        removeHide = false;
                }
                if (mapitem.MapX == myCreatureBase.MapX && mapitem.MapY == myCreatureBase.MapY && mapitem.isDark(null) == true)
                    removeHide = false;

                if (mapitem.MapX == myCreatureBase.MapX && mapitem.MapY == myCreatureBase.MapY)
                    CurrentMapItem = mapitem;
            }
            if (removeHide == false)
                foreach (Character character in CharactersInRange)
                {
                    character.AddMapItem(CurrentMapItem);
                }
            else 
            {
                TargetCreatureBase.buffManager.RemoveBuff(this);
                
                foreach (Character character in CharactersInRange)
                    character.AddCreatureBase(TargetCreatureBase);


                if (TargetCreatureBase is Character)
                {
                    Character character = (Character)TargetCreatureBase;

                    Message msg = new Message();
                    msg.CreatureID = character.CreatureID;
                    msg.Type = "server";
                    msg.Text = "Spell Failed! Nowhere to hide";

                    character.AddMessage(msg);
                    character.PlaySound("Ding", character.MapX, character.MapY);
                }
                return;
            }

            TargetCreatureBase.buffManager.UpdateBuffs();

            //Start Spell Timer
            spellTimer.Start();
        }

        public override void RemoveSpell(bool updateBuffs, bool sendMessage)
        {
            base.RemoveSpell(updateBuffs, sendMessage);
            
            //If updateBuffs & sendMessage is turned off then another hide replaced this or we died, either case we will not need to update the mapitem
            if (updateBuffs == false && sendMessage == false)
                return;

            LockItem lockitem = TargetCreatureBase.GameHandler.GetLockItem(TargetCreatureBase.MapID, TargetCreatureBase.Instance);
            lock (lockitem.LockObj)
            {
                Map CurrentMap = TargetCreatureBase.GameHandler.GetMap(TargetCreatureBase.MapID, TargetCreatureBase.Instance);

                MapItem CurrentMapItem = null;
                List<Character> CharactersInRange = new List<Character>();
                foreach (MapItem mapitem in CurrentMap.MapItems)
                {
                    if (Math.Abs(mapitem.MapX - TargetCreatureBase.MapX) <= 4 && Math.Abs(mapitem.MapY - TargetCreatureBase.MapY) <= 4)
                    {
                        foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                        {
                            if (creaturebase is Character && creaturebase != TargetCreatureBase)
                                CharactersInRange.Add((Character)creaturebase);
                        }
                    }
                    if (mapitem.MapX == TargetCreatureBase.MapX && mapitem.MapY == TargetCreatureBase.MapY)
                        CurrentMapItem = mapitem;
                }
                foreach (Character character in CharactersInRange)
                {
                    character.AddMapItem(CurrentMapItem);
                }
            }
        }
    }
}
